0957. N 天后的牢房【中等】
1. 📝 题目描述
监狱中 8 间牢房排成一排,每间牢房可能被占用或空置。
每天,无论牢房是被占用或空置,都会根据以下规则进行变更:
- 如果一间牢房的两个相邻的房间都被占用或都是空的,那么该牢房就会被占用。
- 否则,它就会被空置。
注意:由于监狱中的牢房排成一行,所以行中的第一个和最后一个牢房不存在两个相邻的房间。
给你一个整数数组 cells,用于表示牢房的初始状态:如果第 i 间牢房被占用,则 cell[i]==1,否则 cell[i]==0。另给你一个整数 n。
请你返回 n 天后监狱的状况(即,按上文描述进行 n 次变更)。
示例 1:
txt
输入:cells = [0,1,0,1,1,0,0,1], n = 7
输出:[0,0,1,1,0,0,0,0]
解释:下表总结了监狱每天的状况:
Day 0: [0, 1, 0, 1, 1, 0, 0, 1]
Day 1: [0, 1, 1, 0, 0, 0, 0, 0]
Day 2: [0, 0, 0, 0, 1, 1, 1, 0]
Day 3: [0, 1, 1, 0, 0, 1, 0, 0]
Day 4: [0, 0, 0, 0, 0, 1, 0, 0]
Day 5: [0, 1, 1, 1, 0, 1, 0, 0]
Day 6: [0, 0, 1, 0, 1, 1, 0, 0]
Day 7: [0, 0, 1, 1, 0, 0, 0, 0]1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
示例 2:
txt
输入:cells = [1,0,0,1,0,0,1,0], n = 1000000000
输出:[0,0,1,1,1,1,1,0]1
2
2
提示:
cells.length == 8cells[i]为0或11 <= n <= 10^9
2. 🎯 s.1 - 周期检测
js
/**
* @param {number[]} cells
* @param {number} n
* @return {number[]}
*/
var prisonAfterNDays = function (cells, n) {
const next = (state) => {
const res = new Array(8).fill(0)
for (let i = 1; i < 7; i++) {
res[i] = state[i - 1] === state[i + 1] ? 1 : 0
}
return res
}
const seen = new Map()
let state = cells
for (let day = 0; day < n; day++) {
const key = state.join('')
if (seen.has(key)) {
const cycleLen = day - seen.get(key)
const remaining = (n - day) % cycleLen
for (let i = 0; i < remaining; i++) state = next(state)
return state
}
seen.set(key, day)
state = next(state)
}
return state
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
- 时间复杂度:
,其中 是有效状态位数,周期不超过 64 - 空间复杂度:
,存储已见状态
算法思路:
- 模拟每天的变化,记录每种状态首次出现的天数
- 当检测到循环时,利用周期长度快速跳过剩余天数
- 第一个和最后一个牢房始终为 0,实际只有中间 6 个牢房有变化